package com.ericsson.smart;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.ericsson.smart.constant.DimensionEnum;
import com.ericsson.smart.constant.HierarchyEnum;
import com.report.meta.DimentionType;
import com.report.meta.ReportType;
import com.report.meta.SelectionDisplayType;
import com.report.meta.SelectionType;
@Component
public class UtilityCommon<T> {

	private static UtilityCommon<?> utilityCommon = null;

	private Map<String, Object> reportMetaData;

	private Map<String, ArrayList<T>> hierarchyMetaData;
@Autowired
	private UtilityDimensionDAO dimensionDAO ;

	private UtilityCommon() {
	}

	@SuppressWarnings("rawtypes")
//	public static UtilityCommon getInstance() {
//		if (utilityCommon == null) {
//			utilityCommon = new UtilityCommon<String>();
//		}
//		return utilityCommon;
//	}

	public Map<String, Object> getReportMetaData() {
		return reportMetaData;
	}

	public void setReportMetaData(Map<String, Object> reportMetaData) {
		this.reportMetaData = reportMetaData;
	}

	public Map<String, ArrayList<T>> getHierarchyMetaData() {
		return hierarchyMetaData;
	}

	public void setHierarchyMetaData(Map<String, ArrayList<T>> hierarchyMetaData) {
		this.hierarchyMetaData = hierarchyMetaData;
	}

	// HIERARCHY_RELATED_METHOD
	public List<String> getNextOrderSelectionValues(String dimName,
			String nextOrderLevelName, Map<String, Object> currentLevelMap) {
		DimensionEnum dimEnum = getDetailsForDimension(dimName);
		List<String> selectionValueList = null;
		selectionValueList = dimensionDAO.getDynamicDistinctList(
				dimEnum.getTable(), nextOrderLevelName, String.class,
				currentLevelMap, true);
		return selectionValueList;
	}

	// HIERARCHY_RELATED_METHOD
	public List<String> getSelectionValues(String dimName,
			String currentLevelName, Map<String, Object> currentLevelMap) {
		System.out.println("Inside getSelectionValues() method...");
		System.out.println("dimName ......" + dimName);
		if (dimName == null) {
			System.out.println("NULL Hierarchy Name is given as input: "
					+ dimName);
			return null;
		} else if (dimName.trim().equals("")) {
			System.out.println("BLANK Hierarchy Name is given as input: "
					+ dimName);
			return null;
		}

		if (currentLevelName == null) {
			System.out
					.println("NULL Present Hierarchy Level is given as input: "
							+ dimName);
			return null;
		} else if (currentLevelName.trim().equals("")) {
			System.out
					.println("BLANK Present Hierarchy Level is given as input: "
							+ dimName);
			return null;
		}

		DimensionEnum dimEnum = getDetailsForDimension(dimName);
		System.out.println("Enum value of dimEnum is......" + dimEnum);
		List<String> outputColumnList = new ArrayList<String>();
		outputColumnList.add(currentLevelName);
		List<String> selectionValueList = null;

		selectionValueList = dimensionDAO.getDynamicDistinctList(
				dimEnum.getTable(), currentLevelName, String.class,
				currentLevelMap, true);

		return selectionValueList;
	}

	// HIERARCHY_RELATED_METHOD
	public String getHierarchyLevelName(String dimName, String levelId) {
		System.out.println("Inside getHierarchyLevelName() method...");
		if (dimName == null) {
			System.out.println("NULL Hierarchy Name is given as input: "
					+ dimName);
			return null;
		} else if (dimName.trim().equals("")) {
			System.out.println("BLANK Hierarchy Name is given as input: "
					+ dimName);
			return null;
		} else {
			return (String) hierarchyMetaData.get(dimName).get(
					Integer.parseInt(levelId) - 1);
		}
	}

	// HIERARCHY_RELATED_METHOD
	public String getNextHierarchyLevelName(String dimName,
			String curdimLevelName) {
		System.out.println("Inside getNextHierarchyLevelName() method...");
		if (dimName == null) {
			System.out.println("NULL Hierarchy Name is given as input: "
					+ dimName);
			return null;
		} else if (dimName.trim().equals("")) {
			System.out.println("BLANK Hierarchy Name is given as input: "
					+ dimName);
			return null;
		} else {
			ArrayList<T> hierList = hierarchyMetaData.get(dimName.trim());
			int currentIndex;
			if (hierList == null) {
				System.out.println("Hierarchy List NOT FOUND for Hierarchy: "
						+ dimName);
				return null;
			} else {
				if (hierList.contains(curdimLevelName.trim())) {
					currentIndex = hierList.indexOf(curdimLevelName.trim());
					if (currentIndex == hierList.size() - 1) {
						System.out
								.println("NO MORE LEVEL. Current Hierachy Level : "
										+ curdimLevelName
										+ " is LAST LEVEL for Hierarchy: "
										+ dimName);
						return curdimLevelName.trim();
					} else {
						return ((String) hierList.get(currentIndex + 1)).trim();
					}
				} else {
					System.out.println("Current Hierachy Level : "
							+ curdimLevelName + " NOT FOUND for Hierarchy: "
							+ dimName);
					return null;
				}
			}
		}
	}

	// HIERARCHY_RELATED_METHOD
	public String getPreviousHierarchyLevelName(String dimName,
			String curDimLevelName) {
		if (dimName == null) {
			System.out.println("NULL Hierarchy Name is given as input: "
					+ dimName);
			return null;
		} else if (dimName.trim().equals("")) {
			System.out.println("BLANK Hierarchy Name is given as input: "
					+ dimName);
			return null;
		} else {
			ArrayList<T> hierList = hierarchyMetaData.get(dimName.trim());
			int currentIndex;
			if (hierList == null) {
				System.out.println("Hierarchy List NOT FOUND for Hierarchy: "
						+ dimName);
				return null;
			} else {
				if (hierList.contains(curDimLevelName.trim())) {
					currentIndex = hierList.indexOf(curDimLevelName.trim());
					if (currentIndex == 0) {
						System.out
								.println("NO MORE LEVEL. Current Hierachy Level : "
										+ curDimLevelName
										+ " is FIRST LEVEL for Hierarchy: "
										+ dimName);
						return curDimLevelName.trim();
					} else {
						return ((String) hierList.get(currentIndex - 1)).trim();
					}
				} else {
					System.out.println("Current Hierachy Level : "
							+ curDimLevelName + " NOT FOUND for Hierarchy: "
							+ dimName);
					return null;
				}
			}
		}
	}

	// HIERARCHY_RELATED_METHOD
	public T getLowestDimLevelFromList(String dimName, ArrayList<String> dimList) {
		// int lowestDimOrder = -1;
		System.out.println("Inside getLowestDimLevelFromList() method...");
		int lowestDimOrder = 0;
		ArrayList<T> hierList;
		if (dimName == null) {
			System.out.println("NULL Hierarchy Name is given as input: "
					+ dimName);
			return null;
		} else if (dimName.trim().equals("")) {
			System.out.println("BLANK Hierarchy Name is given as input: "
					+ dimName);
			return null;
		} else {
			System.out.println("Inside else black in getLowestDimLevelFromList() method.......");
			hierList = hierarchyMetaData.get(dimName);
			System.out.println("hierList is....."+hierList);
			for(int i=0;i<hierList.size();i++) {
			 System.out.println("Hier List: " + hierList.get(i));
			 }
			if (dimList != null) {
				for (String dimension : dimList) {
					 System.out.println("Lowest DIM: " + dimName +
					 " : Value : " + dimension);
					if (hierList.indexOf(dimension.trim()) > lowestDimOrder) {
						lowestDimOrder = hierList.indexOf(dimension);
					}
				}
			}
		}
		// /System.out.println("Return: Index:"+lowestDimOrder + " : Value:"
		// +hierList.get(lowestDimOrder));
		return hierList.get(lowestDimOrder);
	}

	// DIMENSION_RELATED_METHOD
	public HierarchyEnum getHierachyForDimension(String dimName) {
		if (dimName.equalsIgnoreCase("DIM_GEOGRAPHY")) {
			return HierarchyEnum.HIERARCHY_GEOGRAPHY;
		} else if (dimName.equalsIgnoreCase("DIM_TIME")) {
			return HierarchyEnum.HIERARCHY_TIME;
		} else if (dimName.equalsIgnoreCase("DIM_SUBSTATION")) {
			return HierarchyEnum.HIERARCHY_SUBSTATION;
		} else {
			return null;
		}
	}

	// DIMENSION_RELATED_METHOD
	public DimensionEnum getDetailsForDimension(String dimName) {
		System.out.println("Inside getDetailsForDimension() method....");
		if (dimName.equalsIgnoreCase("DIM_GEOGRAPHY")) {
			return DimensionEnum.DIM_GEOGRAPHY;
		} else if (dimName.equalsIgnoreCase("DIM_TIME")) {
			return DimensionEnum.DIM_TIME;
		} else if (dimName.equalsIgnoreCase("DIM_SUBSTATION")) {
			return DimensionEnum.DIM_SUBSTATION;
		} else if (dimName.equalsIgnoreCase("DIM_CUSTOMER")) {
			return DimensionEnum.DIM_CUSTOMER;
		} else if (dimName.equalsIgnoreCase("DIM_TRANSFORMER_METER_TYPE")) {
			return DimensionEnum.DIM_TRANSFORMER_METER_TYPE;
		} else if (dimName.equalsIgnoreCase("DIM_SEVERITY")) {
			return DimensionEnum.DIM_SEVERITY;
		} else {
			return null;
		}
	}

	// DIMENSION_RELATED_METHOD
	public String getTableForDimension(String dimName) {
		DimensionEnum dimEnum = getDetailsForDimension(dimName);
		return dimEnum.getTable();
	}

	// DIMENSION_RELATED_METHOD
	public String getIdColumnForDimension(String dimName) {
		System.out.println("Inside getIdColumnForDimension() method.....");
		DimensionEnum dimEnum = getDetailsForDimension(dimName);
		System.out.println("dimEnum.getIdColumn()........"
				+ dimEnum.getIdColumn());
		return dimEnum.getIdColumn();
	}

	// REPORT_RELATED_METHOD
	public List<String> getReportNames() {
		List<String> reportNames = new ArrayList<String>(
				reportMetaData.keySet());
		return reportNames;
	}

	// REPORT_RELATED_METHOD
	public String getReportAggregateFunction(String reportName) {
		if (!reportMetaData.containsKey(reportName.trim())) {
			System.out
					.println("ERROR: REPORT-DIMENSION-RETRIEVAL: No Reprot found with name: "
							+ reportName);
			return null;
		}
		ReportType report = (ReportType) reportMetaData.get(reportName);
		return report.getReportID();
	}

	// REPORT_RELATED_METHOD
	public List<String> getReportDimensionDetails(String reportName) {
		System.out.println("Inside getReportDimensionDetails() method...");
		if (!reportMetaData.containsKey(reportName.trim())) {
			System.out
					.println("ERROR: REPORT-DIMENSION-RETRIEVAL: No Reprot found with name: "
							+ reportName);
			return null;
		}
		List<String> reportDimensionDetailts = new ArrayList<String>();
		String dimensionDetailts = "";
		ReportType report = (ReportType) reportMetaData.get(reportName);
		List<DimentionType> reportDimensions = report.getReportDimentions();
		for (DimentionType reportDimension : reportDimensions) {
			dimensionDetailts = "";
			List<SelectionType> selectionCriterias = reportDimension
					.getSelectionCriteria();
			for (SelectionType selectionCriteria : selectionCriterias) {
				SelectionDisplayType selectionDisplayType = selectionCriteria
						.getSelectionDisplayType();
				System.out
						.println("reportDimension.getDimentionName() inside getReportDimensionDetails() method is ..."
								+ reportDimension.getDimentionName());
				System.out
				.println("selectionCriteria.getSelectionID() inside getReportDimensionDetails() method is ..."
						+ selectionCriteria.getSelectionID());

				System.out
				.println("selectionDisplayType.getDisplayTypeName() inside getReportDimensionDetails() method is ..."
						+ selectionDisplayType.getDisplayTypeName());
				dimensionDetailts = reportDimension.getDimentionName().trim()
						+ "," + selectionCriteria.getSelectionID().trim() + ","
						+ selectionDisplayType.getDisplayTypeName();
				reportDimensionDetailts.add(dimensionDetailts);
			}
		}
		return reportDimensionDetailts;
	}

}
